package com.gongzonqiang.service.impl;

import java.util.List;
import java.util.Vector;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.gongzonqiang.exception.NoticeException;
import com.gongzonqiang.exception.UserException;
import com.gongzonqiang.mapper.CategoryMapper;
import com.gongzonqiang.mapper.CollectionMapper;
import com.gongzonqiang.mapper.CommentMapper;
import com.gongzonqiang.mapper.MessageMapper;
import com.gongzonqiang.mapper.NoticeMapper;
import com.gongzonqiang.mapper.PriceMapper;
import com.gongzonqiang.mapper.UserMapper;
import com.gongzonqiang.myenum.NoticeEnum;
import com.gongzonqiang.myenum.UserEnum;
import com.gongzonqiang.pojo.Category;
import com.gongzonqiang.pojo.Collection;
import com.gongzonqiang.pojo.Comment;
import com.gongzonqiang.pojo.Message;
import com.gongzonqiang.pojo.Notice;
import com.gongzonqiang.pojo.Price;
import com.gongzonqiang.pojo.User;
import com.gongzonqiang.povo.CommentVo;
import com.gongzonqiang.povo.NoticeVo;
import com.gongzonqiang.service.NoticeService;
import com.gongzonqiang.utils.IDUtil;

import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service
@Transactional
public class NoticeServiceImpl implements NoticeService {
	@Autowired
	private CategoryMapper categoryMapper;
	@Autowired
	private PriceMapper priceMapper;
	@Autowired
	private UserMapper userMapper;
	@Autowired
	private NoticeMapper noticeMapper;
	@Autowired
	private CollectionMapper collectionMapper;
	@Autowired
	private CommentMapper commentMapper;
	@Autowired
	private MessageMapper messageMapper;

	/**
	 * 查看公告详情
	 * 
	 * @param noticeId 公告id
	 * @return 公告信息Vo (包含公告信息,发布公告用户基本信息(昵称,头像,电话),评论(评论人昵称,头像,评论内容,评论时间))
	 */
	public NoticeVo noticeDesc(Long noticeId) {
		NoticeVo noticeVo = new NoticeVo();
		// 查公告信息
		Notice notice = noticeMapper.selectByPrimaryKey(noticeId);
		BeanUtils.copyProperties(notice, noticeVo);
		// 查发布公告用户基本信息
		User user = userMapper.selectByPrimaryKey(noticeVo.getOpenid());
		noticeVo.setNickname(user.getNickname());
		noticeVo.setHeadimg(user.getHeadimg());
		noticeVo.setPhone(notice.getPhone());
		// 分类信息
		Category category = categoryMapper.selectByPrimaryKey(noticeVo.getCategoryId());
		noticeVo.setCategory(category);
		// 查公告评论信息
		PageInfo<CommentVo> commentByNoticeId = commentByNoticeId(1, 999999, noticeId);
		noticeVo.setPageInfos(commentByNoticeId);
		// 浏览数加1
		NoticeVo noticeVo2 = new NoticeVo();
		noticeVo2.setNoticeId(noticeVo.getNoticeId());
		noticeVo2.setBrowseNum(noticeVo.getBrowseNum() + 1);
		noticeMapper.updateByPrimaryKeySelective(noticeVo2);

		return noticeVo;
	}

	/**
	 * 通用查詢Notice表中数据
	 * 
	 * @param pageNum  第几页
	 * @param pageSize 多少条记录
	 * @param notice   公告Vo实体对象
	 * @param order 0置顶优先,其次时间  1置顶优先其次浏览数
	 * @return 公告Vo实体对象(分页)
	 */
	public PageInfo<NoticeVo> selectNoticeVo(int pageNum, int pageSize, NoticeVo notice,Integer order, boolean isAdmin) {
		List<NoticeVo> noticeVos = new Vector<NoticeVo>();
		NoticeVo noticeVo = null;
		Example noticeExample = new Example(Notice.class);
		if(order==0) { 	// 排序规则置顶优先,发布时间 其次
			noticeExample.setOrderByClause("price_id desc,create_date desc");
		}else {	// 排序规则置顶优先,浏览数 其次
			noticeExample.setOrderByClause("price_id desc,browse_num desc");
		}
		
//		if(notice.getNickname() !=null) {
//			userMapper.s
//		}
		
		Criteria criteria2 = noticeExample.createCriteria();
		// 不为null 查分类下;为null 查所有
		if (notice != null) {
			if (!StringUtils.isEmpty(notice.getCategoryId())) {
				criteria2.andEqualTo("categoryId", notice.getCategoryId());
			}
			if (!StringUtils.isEmpty(notice.getOpenid())) {
				criteria2.andEqualTo("openid", notice.getOpenid());
			}
			if (!StringUtils.isEmpty( notice.getContent() )) {
				criteria2.andLike("content", "%" + notice.getContent() + "%");
			}
			if (!StringUtils.isEmpty(notice.getNoticeId())) {
				criteria2.andEqualTo("noticeId", notice.getNoticeId());
			}
			if (!StringUtils.isEmpty(notice.getStatus() )) {
				criteria2.andEqualTo("status", notice.getStatus());
			}
		}
		// 如果不是管理员
		if (!isAdmin) {

			// 只允许用户查看状态为发布中的公告
			criteria2.andEqualTo("status", "1");
		}

		PageHelper.startPage(pageNum, pageSize);
		// PageInfo创建对象前要加上 PageHelper.start(pageNum,pageSize);
		PageInfo pageInfo = new PageInfo(noticeMapper.selectByExample(noticeExample));

		// 查询发布公告用户信息
		// 指定返回字段
		String[] userProperties = { "nickname", "headimg", "phone" };
		for (Notice notice2 : (List<Notice>) pageInfo.getList()) {
			Example userExample = new Example(User.class);
			userExample.selectProperties(userProperties);
			Criteria criteria = null;
			criteria = userExample.createCriteria();
		
			noticeVo = new NoticeVo();
			BeanUtils.copyProperties(notice2, noticeVo);
			criteria.andEqualTo("openid", notice2.getOpenid());
//			System.out.println("notice2.getOpenid():"+notice2.getOpenid());
			User user = userMapper.selectOneByExample(userExample);
			noticeVo.setNickname(user.getNickname());
			noticeVo.setHeadimg(user.getHeadimg());
			// TODO 不应该是用户的手机号，应该是公告的
			noticeVo.setPhone(user.getPhone());
			
			// 分类
			Category category = categoryMapper.selectByPrimaryKey(notice2.getCategoryId());
			noticeVo.setCategory(category);
			noticeVos.add(noticeVo);
		}
		pageInfo.setList(noticeVos);

		return pageInfo;
	}

	/**
	 * 	* 公告列表(首页)(包含轮播公告(公告编号,图片链接)		 获取轮播图公告
	 * 
	 * @return 首页Vo对象
	 */
	public List<Notice> listNoticeForIndex() {
//		NoticeVoForIndexVo noticeVoForIndexVo = new NoticeVoForIndexVo();
		// 查轮播公告
		Notice notice = new Notice();
		notice.setCarousel(1);
		notice.setStatus(1);
//		noticeVoForIndexVo.setCarouselNotice(noticeMapper.select(notice));

//		//查普通公告
//		//指定查询字段 通过selectNoticeVo方法 NoticeVo为null查所有
//		noticeVoForIndexVo.setNoticevos(selectNoticeVo(1,5,null,false));

		return noticeMapper.select(notice);
	}
	
	/**
	 * 管理员修改公告
	 * @param notice 公告实体对象
	 * @return 
	 */
	public int updateNotice(Notice notice) {
		return noticeMapper.updateByPrimaryKeySelective(notice);
	}
	/**
	 * 查看分类下的商品
	 * 
	 * @param categoryId 分类id
	 * @return 公告信息Vo(置顶和非置顶;包含公告信息,发布公告用户基本信息(昵称,头像,电话);分页)
	 */
	public PageInfo<NoticeVo> listNoticeByCategory(int pageNum, int pageSize, int order,Long categoryId) {
		NoticeVo noticeVo = new NoticeVo();
		noticeVo.setCategoryId(categoryId);

		return selectNoticeVo(pageNum, pageSize,noticeVo, order, false);
	}

	/**
	 * 搜索公告(条件可以为:公告内容,用户名称,公告id)
	 * 
	 * @param notice 公告实体对象
	 * @return 公告信息Vo(置顶和非置顶;包含公告信息,发布公告用户基本信息(昵称,头像,电话);分页)
	 */
	public PageInfo<NoticeVo> searchNotice(int pageNum, int pageSize, NoticeVo notice) {
		return selectNoticeVo(pageNum, pageSize, notice,1,  false);
	};

	/**
	 * 评论公告(同时要创建一条消息通知)
	 * 
	 * @param comment 评论实体对象
	 * @param user    用户实体对象
	 * @return 0失败 1成功
	 */
	public int comment(Comment comment, User user) {
		isLogin(user);

		comment.setCommentId(IDUtil.getId());
		comment.setOpenid(user.getOpenid());
		// 没有插入成功
		if (0 == commentMapper.insertSelective(comment)) {
			return 0;
		}

		// 创建消息通知
		// 先判断该公告是否已有消息通知
		Message message = new Message();
		message.setNoticeId(comment.getNoticeId());
		// 已有消息通知
		if (messageMapper.selectCount(message) == 1) {
			return 1;
		}
		message.setMessageId(IDUtil.getId());
		message.setOpenid(comment.getOpenid());
		message.setStatu(0);

		return messageMapper.insertSelective(message);
	}

	/**
	 * 用户删除自己的评论
	 * 
	 * @param commentId 评论编号
	 * @param user      用户实体
	 * @return 0失败 1成功
	 */
	public int delComment(Long commentId, User user) {
		isLogin(user);

		Comment comment = new Comment();
		comment.setCommentId(commentId);
		comment.setOpenid(user.getOpenid());

		return commentMapper.delete(comment);
	}

	/**
	 * 发布公告(若想置顶但未支付成功,直接返回提交公告页面)
	 * 
	 * @param notice 公告实体对象
	 * @param user   用户实体对象
	 * @return 0失败 1成功
	 */
	public int release(Notice notice, User user) {
		boolean flag = false;

		isLogin(user);

		// 判断是否需要置顶
		if (notice.getPriceId() != null) {
			// 调用支付接口

			flag = true;

			// 未支付成功 直接返回
			if (!flag) {
				return 0;
			}
		}

		notice.setNoticeId(IDUtil.getId());
		notice.setOpenid(user.getOpenid());
		// 设置审核状态 浏览数 收藏数 转发数
		notice.setStatus(NoticeEnum.RELEASE.getCode());
		notice.setBrowseNum(0);
		notice.setCollectionNum(0);
		notice.setForwardNum(0);

		return noticeMapper.insertSelective(notice);
	}

	/**
	 * 用户删除自己发布的公告
	 * 
	 * @param noticeId 公告id
	 * @param user     用户实体对象
	 * @return 0失败 1成功
	 */
	public int delNotice(Long noticeId, User user) {
		isLogin(user);

		Notice notice = new Notice();
		notice.setNoticeId(noticeId);
		notice.setOpenid(user.getOpenid());
		notice.setStatus(NoticeEnum.DEL.getCode());
		
		return noticeMapper.updateByPrimaryKeySelective(notice);
	};

	/**
	 * 用户收藏公告
	 * 
	 * @param noticeId 公告id
	 * @param user     用户实体对象
	 * @return 0失败 1成功
	 */
	public Collection collect(Long noticeId, User user) {
		isLogin(user);

		Collection collection = new Collection();
		collection.setCollectionId(IDUtil.getId());
		collection.setNoticeId(noticeId);
		collection.setOpenid(user.getOpenid());
		
		Notice notice = noticeMapper.selectByPrimaryKey(noticeId);
		notice.setCollectionNum(notice.getCollectionNum()+1);
		noticeMapper.updateByPrimaryKeySelective(notice);
		int insertSelective = collectionMapper.insertSelective(collection);
		return collection;
	}

	/**
	 * 用户删除自己的收藏
	 * 
	 * @param collectionId 收藏编号
	 * @param user         用户实体对象
	 * @return 0失败 1成功
	 */
	public int delCollection(Long collectionId, User user) {
		isLogin(user);

		Collection coll = collectionMapper.selectByPrimaryKey(collectionId);
		if(coll!=null && coll.getOpenid().equals(user.getOpenid())) {
			Notice notice = noticeMapper.selectByPrimaryKey(coll.getNoticeId());
			notice.setCollectionNum(notice.getCollectionNum()-1);
			noticeMapper.updateByPrimaryKeySelective(notice);

			return collectionMapper.deleteByPrimaryKey(coll.getCollectionId());
		}
		return 0;
	}

	/**
	 * 公告列表(后台管理) (可以使用的条件:分类,名称,公告id)
	 * 
	 * @param notice 公告实体对象
	 * @return 公告Vo对象信息(公告信息(包含公告信息,昵称,电话)(分页))
	 */
	public PageInfo<NoticeVo> listNotice(int pageNum, int pageSize, NoticeVo notice, User user) {
		// 判断是否为管理员
		isAdmin(user);

		return selectNoticeVo(pageNum, pageSize, notice,0,  true);
	}

	/**
	 * 审核(通过,不通过),逻辑删除(管理员操作)
	 * 
	 * @param noticeId 公告编号
	 * @param status   状态(-1不通过 1发布(通过) -2逻辑删除)
	 * @return 0失败 1成功
	 */
	public int checkCollection(Long noticeId, int status) {
		Notice notice = new Notice();
		notice.setNoticeId(noticeId);
		notice.setStatus(status);

		return noticeMapper.updateByPrimaryKeySelective(notice);
	};
	
	/**
	 * 删除评论
	 * @param commentId 评论编号
	 * @param user 管理员账号
	 * @return 0失败 1成功
	 */
	public int delComeentByAdmin(Long commentId) {
		 return commentMapper.deleteByPrimaryKey(commentId);
	}
	
	/**
	 * 查看公告下的评论
	 * 
	 * @param noticeId 公告id
	 * @return 评论Vo信息(評論用户头像和姓名,评论内容,评论时间)(分页)
	 */
	public PageInfo<CommentVo> commentByNoticeId(int pageNum, int pageSize, Long noticeId) {
		User user = null;
		CommentVo commentVo = null;
		List<CommentVo> commentVos = new Vector<CommentVo>();

		// 查评论信息
		Comment comment = new Comment();
		comment.setNoticeId(noticeId);
		PageHelper.startPage(pageNum, pageSize);
		PageInfo pageInfo = new PageInfo(commentMapper.select(comment));

		// 查评论人信息
		for (Comment comment2 : (List<Comment>) pageInfo.getList()) {
			commentVo = new CommentVo();
			commentVo.setCommentContent(comment2.getContent());
			commentVo.setCommentCreateDate(comment2.getCreateDate());
			commentVo.setCommentId(comment2.getCommentId());
			
			user = userMapper.selectByPrimaryKey(comment2.getOpenid());
			commentVo.setCommentHeadImg(user.getHeadimg());
			commentVo.setCommentNickname(user.getNickname());

			commentVos.add(commentVo);
		}
		pageInfo.setList(commentVos);

		return pageInfo;
	}

	/**
	 * 设置公告轮播天数(管理员操作)(为0则取消轮播)
	 * 
	 * @param noticeId    公告编号
	 * @param carouselDay 轮播天数
	 * @return 0失败 1成功
	 */
	public int setCarousel(Long noticeId, int carouselDay) {
		Notice notice = new Notice();
		notice.setNoticeId(noticeId);
		if(carouselDay==0) { //(为0则取消轮播)
			notice.setCarouselDay(0);
			notice.setCarousel(0);
		}else {
			notice.setCarouselDay(carouselDay);
			notice.setCarousel(1);
		}

		return noticeMapper.updateByPrimaryKeySelective(notice);
	}

	/**
	 * 分类列表
	 * 
	 * @return 分类信息(分页)(虽然分类可能会很少,但习惯用了PageInfo,再用其他的也很麻烦)
	 */
	public PageInfo<Category> listCategory(int pageNum, int pageSize) {
		PageHelper.startPage(pageNum, pageSize);

		return new PageInfo<Category>(categoryMapper.selectAll());
	};
	/**
	 *添加分类
	 * @param category 分类实体对象(封装分类信息)
	 * @return 0失败 1成功
	 */
	public int insertCategory(Category category) {
		category.setCategoryId(IDUtil.getId());
		return categoryMapper.insertSelective(category);
	}

	/**
	 * 更新分类 不能删除分类
	 * 
	 * @param category 分类实体对象(封装分类信息)
	 * @return 0失败 1成功
	 */
	public int updateCategory(Category category) {
		return categoryMapper.updateByPrimaryKeySelective(category);
	};

	/**
	 * 价格列表
	 * 
	 * @return 价格信息(分页)
	 */
	public PageInfo<Price> listPrice(int pageNum, int pageSize) {
		PageHelper.startPage(pageNum, pageSize);

		return new PageInfo<Price>(priceMapper.selectAll());
	};

	/**
	 * 添加价格
	 * 
	 * @param price 价格实体对象
	 * @return 0失败 1成功
	 */
	public int insertPrice(Price price, User user) {
		isAdmin(user);

		return priceMapper.insertSelective(price);
	};

	/**
	 * 删除价格(真删,没人使用这个价格才能删)
	 * 
	 * @param priceId 价格编号
	 * @return 0失败 1成功
	 */
	public int delPrice(int priceId, User user) {
		isAdmin(user);

		// 查看所有公告中是否有在使用此价格的(逻辑删除的公告怎么算,那就使用更新价格吧(曲线删除))
		Notice notice = new Notice();
		notice.setPriceId(priceId);
		if (0 != noticeMapper.selectCount(notice)) {
			// 价格在被使用
			throw new NoticeException(NoticeEnum.PRICEUSEING);
		}

		return priceMapper.deleteByPrimaryKey(priceId);
	};

	/**
	 * 更新价格
	 * 
	 * @param price 价格实体
	 * @return 0失败 1成功
	 */
	public int updatePrice(Price price, User user) {
		isAdmin(user);

		return priceMapper.updateByPrimaryKeySelective(price);
	};

	/**
	 * 是否登录
	 * 
	 * @param user 用户实体
	 * @return
	 */
	public boolean isLogin(User user) {
		if (user == null) {
			// 未登录
			throw new UserException(UserEnum.NOLOGIN);
		}

		return true;
	}

	public boolean isAdmin(User user) {
		if (isLogin(user) && user.getStatus() != 2) {
			// 不是管理员
			throw new UserException(UserEnum.NOTADMIN);
		}

		return true;
	}

	/**
	 * 根据分类id获取分类
	 * 
	 * @param cid
	 * @return
	 */
	@Override
	public Category selectCategoryByCid(Long cid) {
		return categoryMapper.selectByPrimaryKey(cid);
	}
	
	/**
	 *判断用户是否收藏 
	 * @param noticeId 公告编号
	 * @param user 用户实体
	 * @return 
	 */
	public Collection isCollect(Long noticeId, User user) {
		isLogin(user);
		
		Collection collection = new Collection();
		collection.setNoticeId(noticeId);
		collection.setOpenid(user.getOpenid());
		
		return collectionMapper.selectOne(collection);
	}
	
	/**
	 * 用户删除自己的评论
	 * @param commentId 评论编号
	 * @param user 用户实体
	 * @return 0失败 1成功
	 */
	@Override
	public int delNoticeByAdmin(Long noticeId) {
		Notice notice = new Notice();
		notice.setNoticeId(noticeId);
		notice.setStatus(NoticeEnum.DEL.getCode());
		
		return noticeMapper.updateByPrimaryKeySelective(notice);
	}
}
